/**
 * Copyright (c) 2009 RiseSoft Co.,Ltd  
 * $Header$
 */
package net.risesoft.risebi.collection.web.admin;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.risesoft.risebi.collection.model.Application;
import net.risesoft.risebi.collection.model.Catalog;
import net.risesoft.risebi.collection.model.DbColumn;
import net.risesoft.risebi.collection.model.ObjectPermission;
import net.risesoft.risebi.collection.model.Service;
import net.risesoft.risebi.collection.model.Speciality;
import net.risesoft.risebi.collection.model.StatisticalObjectTree;
import net.risesoft.risebi.collection.model.StatisticalObjectTreeNode;
import net.risesoft.risebi.collection.model.User;
import net.risesoft.risebi.collection.service.ApplicationManager;
import net.risesoft.risebi.collection.service.CatalogManager;
import net.risesoft.risebi.collection.service.DbMetaDataManager;
import net.risesoft.risebi.collection.service.PrivilegeManager;
import net.risesoft.risebi.collection.service.ServiceManager;
import net.risesoft.risebi.collection.service.SpecialityManager;
import net.risesoft.risebi.collection.service.StatisticalObjectTreeManager;
import net.risesoft.risebi.collection.service.StatisticalObjectTreeNodeManager;
import net.risesoft.risebi.collection.web.BaseAction;
import net.risesoft.risebi.commons.struts2extension.Trimable;
import net.risesoft.risebi.commons.util.GUID;
import net.risesoft.risebi.commons.util.JSONUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.beanutils.LazyDynaBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionInvocation;

/**
 *
 * @author <a href="mailto: dingzhaojun@risesoft.net">丁兆俊</a>
 * @version $Revision$
 * 
 */
@Namespace("/admin/SoTreeAction")
public class SoTreeAction extends BaseAction implements Trimable{
	private static final long serialVersionUID = -1517818004703827102L;
	private static Log log = LogFactory.getLog(SoTreeAction.class);
	
	private ServiceManager serviceManager;	
	private ApplicationManager applicationManager;	
	private CatalogManager catalogManager;	
	private StatisticalObjectTreeManager statisticalObjectTreeManager;
	private StatisticalObjectTreeNodeManager statisticalObjectTreeNodeManager;
	private SpecialityManager specialityManager;
	private PrivilegeManager privilegeManager;
	private DbMetaDataManager dbMetaDataManager;
	
	private StatisticalObjectTree statisticalObjectTree;
	private StatisticalObjectTreeNode statisticalObjectTreeNode;
	
	private String serviceGuid;
	private String applicationGuid;
	private String applicationName;

	private String tableName;
	private String crud;

	@Action(value="prepareSoTreeList",
			results={@Result(name="success", location="/admin/soTree/soTreeList.jsp")}
	)
	public String prepareSoTreeList() throws Exception {
		return SUCCESS;
	}
	
	@Action(value="prepareSoTreeAdd",
			results={@Result(name="success", location="/admin/soTree/soTreeAdd.jsp")}
	)
	public String prepareSoTreeAdd() throws Exception {
		return SUCCESS;
	}

	@Action(value="prepareSoTreeEdit",
			results={@Result(name="success", location="/admin/soTree/soTreeEdit.jsp")}
	)
	public String prepareSoTreeEdit() throws Exception {
		this.statisticalObjectTree = (StatisticalObjectTree)statisticalObjectTreeManager.getObject(StatisticalObjectTree.class, this.node);
		if(this.statisticalObjectTree.getTabIndex()==null) this.statisticalObjectTree.setTabIndex(1.0);
		if(this.statisticalObjectTree.getEnabled()==null) this.statisticalObjectTree.setEnabled(true);
		//if(this.statisticalObjectTree.getType()==null) this.statisticalObjectTree.setType(1);
		
		return SUCCESS;
	}

	@Action(value="prepareListSoTree",
			results={@Result(name="success", location="/admin/soTree/listSoTree.jsp")}
	)
	public String prepareListSoTree() throws Exception {	
		Application app = (Application)applicationManager.getObject(Application.class, this.applicationGuid);
		this.applicationName = app.getChineseName();
		
		return SUCCESS;
	}

	@Action(value="prepareSelectSoTree",
			results={@Result(name="success", location="/admin/soTree/selectSoTree.jsp")}
	)
	public String prepareSelectSoTree() throws Exception {	
		Application app = (Application)applicationManager.getObject(Application.class, this.applicationGuid);
		if(app != null){
			this.applicationName = app.getChineseName();
			
			List<StatisticalObjectTree> lst = statisticalObjectTreeManager.getAllByApp(this.applicationGuid);
			List newList = new ArrayList();
			for(StatisticalObjectTree t : lst){
				Map map = new HashMap();
				map.put("checked", false);
				if(t.getGuid().trim().equals(this.node.trim())){
					map.put("checked", true);
				}
				map.put("guid", t.getGuid());
				map.put("name", t.getName());
				map.put("description", t.getDescription());
				map.put("enabled", t.getEnabled());
				newList.add(map);
			}
			this.json = JSONUtil.getJsonString(null, null, newList);
		}else{
			this.json = "[]";
		}
		
		return SUCCESS;
	}
	
	@Action(value="prepareSoTreeNodeList",
			results={@Result(name="success", location="/admin/soTree/soTreeNodeList.jsp")}
	)
	public String prepareSoTreeNodeList() throws Exception {	
		return SUCCESS;
	}

	@Action(value="prepareSelectColumn",
			results={@Result(name="success", location="/admin/soTree/selectColumn.jsp")}
	)
	public String prepareSelectColumn() throws Exception {			
		return SUCCESS;
	}

	@Action(value="prepareSelectSoTreeNode",
			results={@Result(name="success", location="/admin/soTree/selectSoTreeNode.jsp")}
	)
	public String prepareSelectSoTreeNode() throws Exception {			
		return SUCCESS;
	}

	@Action(value="addTree")
	public String addTree() throws Exception {
		LazyDynaBean ldb = new  LazyDynaBean();
		try{
			if(this.statisticalObjectTree.getGuid()==null || this.statisticalObjectTree.getGuid().trim().length()==0 || this.statisticalObjectTree.getGuid().startsWith("NEW")){
				this.statisticalObjectTree.setGuid(new GUID().toString());
			}
			statisticalObjectTreeManager.saveObject(this.statisticalObjectTree);
			
			ldb.set("guid", statisticalObjectTree.getGuid());
			ldb.set("name", statisticalObjectTree.getName());
			ldb.set("description", statisticalObjectTree.getDescription());
			ldb.set("iconPath", statisticalObjectTree.getIconPath());
			ldb.set("enabled", statisticalObjectTree.getEnabled());
			ldb.set("tabIndex", statisticalObjectTree.getTabIndex());
			
			ldb.set("success", true);
			ldb.set("reason", "增加成功!");
			this.json = JSONObject.fromObject(ldb).toString();
		}catch(Exception e){
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
			this.json = JSONObject.fromObject(ldb).toString();
			e.printStackTrace();
		}

		return AJAX;
	}

	@Action(value="addTreeNode")
	public String addTreeNode() throws Exception {
		LazyDynaBean ldb = new  LazyDynaBean();
		try{
			if(this.statisticalObjectTreeNode.getGuid()==null || this.statisticalObjectTreeNode.getGuid().trim().length()==0 || this.statisticalObjectTreeNode.getGuid().startsWith("NEW")){
				this.statisticalObjectTreeNode.setGuid(new GUID().toString());
			}
			statisticalObjectTreeNode.setTabIndex(100.0);
			
			statisticalObjectTreeNodeManager.saveObject(this.statisticalObjectTreeNode);
			
			ldb.set("success", true);
			ldb.set("reason", "增加成功!");
			this.json = JSONObject.fromObject(ldb).toString();
		}catch(Exception e){
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
			this.json = JSONObject.fromObject(ldb).toString();
			e.printStackTrace();
		}

		return AJAX;
	}

	@Action(value="editTree")
	public String editTree() throws Exception {
		LazyDynaBean ldb = new  LazyDynaBean();
		try{
			statisticalObjectTreeManager.saveObject(this.statisticalObjectTree);
			
			ldb.set("guid", statisticalObjectTree.getGuid());
			ldb.set("name", statisticalObjectTree.getName());
			ldb.set("description", statisticalObjectTree.getDescription());
			ldb.set("iconPath", statisticalObjectTree.getIconPath());
			ldb.set("enabled", statisticalObjectTree.getEnabled());
			ldb.set("tabIndex", statisticalObjectTree.getTabIndex());
			
			ldb.set("success", true);
			ldb.set("reason", "修改成功!");
			this.json = JSONObject.fromObject(ldb).toString();
		}catch(Exception e){
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
			this.json = JSONObject.fromObject(ldb).toString();
			e.printStackTrace();
		}

		return AJAX;
	}

	@Action(value="refreshJson")
	public String refreshJson() throws Exception {
		try{
			if("jsonAppSoTrees".equalsIgnoreCase(this.whichJson)){
				List<StatisticalObjectTree> lst = statisticalObjectTreeManager.getAllByApp(this.applicationGuid);
				this.json = JSONUtil.getJsonString("include", "appGuid,guid,name,description,type,enabled,iconPath,tabIndex", lst);
			}else if("jsonAppTrees".equalsIgnoreCase(this.whichJson)){
				String serviceGuid = this.getDefaultService().getGuid();
				User user = this.getSessionUser();
				ArrayList al = new ArrayList();		
				if(this.active_node_id==null){
					LazyDynaBean ldb = new LazyDynaBean();
					ldb.set("guid", "A12345678");
					ldb.set("parentGuid", "");
					ldb.set("name", "【其他】");
					ldb.set("_node_type", "专业");
					ldb.set("_is_leaf", false);
					al.add(ldb);
					
					List<Speciality> lst = specialityManager.find("from Speciality s where s.service.guid='" + serviceGuid + "' order by s.tabIndex");
					for(Speciality spec : lst){	
						boolean isleaf = true;
						List<Application> lst2 = applicationManager.getAppsByServiceWithPermission(serviceGuid, user);
						for(Application app : lst2){
							if(spec.getGuid().equalsIgnoreCase(app.getSpecialityGuid())){
								isleaf = false;
								break;
							}
						}
						if(isleaf == false){
							ldb = new LazyDynaBean();
							ldb.set("guid", spec.getGuid());
							ldb.set("parentGuid", "");
							ldb.set("name", "【专业】" + spec.getChineseName());
							ldb.set("_node_type", "专业");
							ldb.set("_is_leaf", false);
							al.add(ldb);
						}
					}					
				}else if("专业".equalsIgnoreCase(this.active_node_type)){
					List<Application> lst;
					if("A12345678".equals(this.active_node_id)){
						lst = (List<Application>) applicationManager.find("from Application app where app.service.guid='" + serviceGuid + "' and (app.speciality.guid is null or trim(app.speciality.guid)='' ) order by app.tabIndex");
					}else{
						lst = (List<Application>) applicationManager.find("from Application app where app.service.guid='" + serviceGuid + "' and app.speciality.guid='" + this.active_node_id + "' order by app.tabIndex");
					}
					
					List<Application> apps = privilegeManager.getAllowedList(lst, ObjectPermission.OBJECTTYPE_APPLICATION,user,null);
					for(Application a : apps){
						LazyDynaBean ldb = new LazyDynaBean();
						ldb.set("guid", a.getGuid());
						ldb.set("parentGuid", this.active_node_id);
						ldb.set("name", "【应用】" + a.getChineseName());
						ldb.set("_node_type", "应用");
						
						boolean isleaf = true;
						List<StatisticalObjectTree> lst2 = statisticalObjectTreeManager.getAllByApp(a.getGuid());
						if(lst2.size()>0){
							isleaf = false;
						}
						ldb.set("_is_leaf", isleaf);						
						al.add(ldb);
					}					
				}else if("应用".equalsIgnoreCase(this.active_node_type)){
					List<StatisticalObjectTree> lst = statisticalObjectTreeManager.getAllByApp(this.active_node_id);
					for(StatisticalObjectTree soTree : lst){
						LazyDynaBean ldb = new LazyDynaBean();
						ldb.set("guid", soTree.getGuid());
						ldb.set("parentGuid", this.active_node_id);
						ldb.set("name", "【树】" + soTree.getName());
						ldb.set("_node_type", "对象树");
						ldb.set("_is_leaf", true);						
						al.add(ldb);
					}					
				}				

				this.json = JSONUtil.getJsonString(null, null, al);				
			}else if("jsonTreeNodes".equalsIgnoreCase(this.whichJson)){
				ArrayList<Map<String,Object>> lst =  statisticalObjectTreeNodeManager.getSotNodesByParentId(this.node, this.active_node_id);				
				this.json = JSONUtil.getJsonString(null, null, lst);	
			}else if("jsonRemainderSO".equalsIgnoreCase(this.whichJson)){
				this.statisticalObjectTree = (StatisticalObjectTree)statisticalObjectTreeManager.getObject(StatisticalObjectTree.class, this.node);
				this.applicationGuid = this.statisticalObjectTree.getAppGuid();

				String soGuids = "";
				List<StatisticalObjectTreeNode> nodes = statisticalObjectTree.getSotNodes();
				for(StatisticalObjectTreeNode node : nodes){
					soGuids += "," + node.getSoGuid();
				}
				
				ArrayList al = new ArrayList();	
				List<Catalog> cs = catalogManager.getCatalogWithSoByApp(this.applicationGuid,true);
				for(Catalog c : cs){
					if(soGuids.indexOf(c.getGuid().trim())>-1){
						continue;
					}else{
						LazyDynaBean ldb = new LazyDynaBean();
						ldb.set("text", "【" + c.getSoType().getName() +"】：" + c.getName());
						ldb.set("type", "so");
						ldb.set("soGuid", c.getGuid());
						ldb.set("cls", "x-btn-text-icon");
						if(this.getContextPath().endsWith("/")){
							ldb.set("icon", this.getContextPath()+"images/system/fam/user.png");
						}else{
							ldb.set("icon", this.getContextPath()+"/images/system/fam/user.png");
						}					
						al.add(ldb);
					}
				}
				if(al.size()==0){
					LazyDynaBean ldb = new LazyDynaBean();
					if(cs.size()==0){
						ldb.set("text", "本应用没有统计调查对象, 请在【应用与模板管理】或【统计调查对象管理】中定义统计调查对象！");
					}else{
						ldb.set("text", "本应用的所有统计调查对象都已加进来，没有新的可以添加！");
					}
					ldb.set("type", "not so");
					ldb.set("soGuid", "not so");
					ldb.set("cls", "x-btn-text-icon");
					if(this.getContextPath().endsWith("/")){
						ldb.set("icon", this.getContextPath()+"images/system/fam/asterisk_orange.png");
					}else{
						ldb.set("icon", this.getContextPath()+"/images/system/fam/asterisk_orange.png");
					}					
					al.add(ldb);
				}
				this.json = JSONUtil.getJsonString(null, null, al);	
			}else if("jsonTableColumns".equalsIgnoreCase(this.whichJson)){
				List<DbColumn> lst = dbMetaDataManager.listAllColumns(this.tableName);
				this.json = JSONUtil.getJsonString("include", "column_name,type_name,data_length,primaryKey,nullable,comment", lst);
			}
		}catch(Exception e){
			this.json = "[]";
			e.printStackTrace();
		} 

		return AJAX;
	}

	@Action(value="saveTreeNodes")
	public String saveTreeNodes() throws Exception {
		LazyDynaBean ldb = new  LazyDynaBean();
		try{
			StatisticalObjectTreeNode[] sotNodes = (StatisticalObjectTreeNode[])JSONUtil.stringToArray(json, StatisticalObjectTreeNode.class);
			for (StatisticalObjectTreeNode s : sotNodes){
				if(s.getGuid()==null || s.getGuid().trim().length()==0 || s.getGuid().startsWith("NEW")){
					s.setGuid(new GUID().toString());
				}
				statisticalObjectTreeNodeManager.saveObject(s);
			}
			
			ldb.set("success", true);
			ldb.set("reason", "保存成功!");
			this.json = JSONObject.fromObject(ldb).toString();
		}catch(Exception e){
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
			this.json = JSONObject.fromObject(ldb).toString();
			e.printStackTrace();
		}

		return AJAX;
	}

	@Action(value="removeTree")
	public String removeTree() throws Exception {
		LazyDynaBean ldb = new  LazyDynaBean();
		try{
			statisticalObjectTreeManager.removeObject(StatisticalObjectTree.class, node);
			
			ldb.set("success", true);
			ldb.set("reason", "删除成功!");
			this.json = JSONObject.fromObject(ldb).toString();
		}catch(Exception e){
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
			this.json = JSONObject.fromObject(ldb).toString();
			e.printStackTrace();
		}
		
		return AJAX;		
	}

	@Action(value="removeTreeNode")
	public String removeTreeNode() throws Exception {
		LazyDynaBean ldb = new  LazyDynaBean();
		try{
			statisticalObjectTreeNodeManager.removeObject(StatisticalObjectTreeNode.class, node);
			
			ldb.set("success", true);
			ldb.set("reason", "删除成功!");
			this.json = JSONObject.fromObject(ldb).toString();
		}catch(Exception e){
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
			this.json = JSONObject.fromObject(ldb).toString();
			e.printStackTrace();
		}
		
		return AJAX;		
	}

	/**
	 * @see net.risesoft.commons.struts2extension.Trimable#afterTrim(com.opensymphony.xwork2.ActionInvocation)
	 */
	public void afterTrim(ActionInvocation invocation) {
		
	}

	/**
	 * @see net.risesoft.commons.struts2extension.Trimable#preTrim(com.opensymphony.xwork2.ActionInvocation)
	 */
	public boolean preTrim(ActionInvocation invocation) {
		return true;
	}
	
	public ServiceManager getServiceManager() {
		return serviceManager;
	}

	public void setServiceManager(ServiceManager serviceManager) {
		this.serviceManager = serviceManager;
	}

	public ApplicationManager getApplicationManager() {
		return applicationManager;
	}

	public void setApplicationManager(ApplicationManager applicationManager) {
		this.applicationManager = applicationManager;
	}

	public SpecialityManager getSpecialityManager() {
		return specialityManager;
	}

	public void setSpecialityManager(SpecialityManager specialityManager) {
		this.specialityManager = specialityManager;
	}

	public PrivilegeManager getPrivilegeManager() {
		return privilegeManager;
	}

	public void setPrivilegeManager(PrivilegeManager privilegeManager) {
		this.privilegeManager = privilegeManager;
	}

	public StatisticalObjectTreeManager getStatisticalObjectTreeManager() {
		return statisticalObjectTreeManager;
	}

	public void setStatisticalObjectTreeManager(
			StatisticalObjectTreeManager statisticalObjectTreeManager) {
		this.statisticalObjectTreeManager = statisticalObjectTreeManager;
	}

	public StatisticalObjectTreeNodeManager getStatisticalObjectTreeNodeManager() {
		return statisticalObjectTreeNodeManager;
	}

	public void setStatisticalObjectTreeNodeManager(
			StatisticalObjectTreeNodeManager statisticalObjectTreeNodeManager) {
		this.statisticalObjectTreeNodeManager = statisticalObjectTreeNodeManager;
	}

	public StatisticalObjectTree getStatisticalObjectTree() {
		return statisticalObjectTree;
	}

	public void setStatisticalObjectTree(StatisticalObjectTree statisticalObjectTree) {
		this.statisticalObjectTree = statisticalObjectTree;
	}

	public StatisticalObjectTreeNode getStatisticalObjectTreeNode() {
		return statisticalObjectTreeNode;
	}

	public void setStatisticalObjectTreeNode(
			StatisticalObjectTreeNode statisticalObjectTreeNode) {
		this.statisticalObjectTreeNode = statisticalObjectTreeNode;
	}

	public DbMetaDataManager getDbMetaDataManager() {
		return dbMetaDataManager;
	}

	public void setDbMetaDataManager(DbMetaDataManager dbMetaDataManager) {
		this.dbMetaDataManager = dbMetaDataManager;
	}

	public CatalogManager getCatalogManager() {
		return catalogManager;
	}

	public void setCatalogManager(CatalogManager catalogManager) {
		this.catalogManager = catalogManager;
	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public String getCrud() {
		return crud;
	}

	public void setCrud(String crud) {
		this.crud = crud;
	}

	public String getServiceGuid() {
		return serviceGuid;
	}

	public void setServiceGuid(String serviceGuid) {
		this.serviceGuid = serviceGuid;
	}

	public String getApplicationGuid() {
		return applicationGuid;
	}

	public void setApplicationGuid(String applicationGuid) {
		this.applicationGuid = applicationGuid;
	}

	public String getApplicationName() {
		return applicationName;
	}

	public void setApplicationName(String applicationName) {
		this.applicationName = applicationName;
	}

}
